﻿using GylCSharpUtils.Common.Base.SpecialConverter;
using System;
using System.Text;

namespace GylCSharpUtils.GSerializer.SpecialConverter {
    public abstract class ValueTypeConverter<T> : ASpecialConverter {

        private ASpecialConverter serial;

        public override Type ConfigType() {
            return typeof(T);
        }

        public ASpecialConverter GetArrConverter() {
            if(serial == null) serial = SpecialConverterManager.GetSpecialConverter(typeof(T[]));
            if(serial == null) throw new Exception($"未找到{ConfigType().FullName}对应的专有序列化器");
            return serial;
        }

        public override object ToObject(byte[] data) {
            return ((T[])GetArrConverter().ToObject(data))[0];
        }

        public override byte[] ToByteArray(object obj) {
            // 按照只有一个元素的数组的方式进行序列化
            return GetArrConverter().GetBytes(new T[] { (T)obj });
        }


    }

    #region 整数
    /// <summary>
    /// 也可以像数组专有序列化工具一样不重写方法，但使用重写后的方法序列化比原本的方法更快捷
    /// </summary>
    public class BoolConverter : ValueTypeConverter<bool> {

        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((bool)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToBoolean(data, 0);
        }

    }

    public class ByteConverter : ValueTypeConverter<byte> {
        public override byte[] ToByteArray(object value) {
            return new byte[] { (byte)value };
        }

        public override object ToObject(byte[] data) {
            return data[0];
        }
    }
    public class ShortConverter : ValueTypeConverter<short> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((short)value);
        }
        public override object ToObject(byte[] data) {
            return BitConverter.ToInt16(data, 0);
        }

    }
    public class IntConverter : ValueTypeConverter<int> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((int)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToInt32(data, 0);
        }

    }
    public class LongConverter : ValueTypeConverter<long> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((long)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToInt64(data, 0);
        }
    }

    public class SByteConverter : ValueTypeConverter<sbyte> {
        public override byte[] ToByteArray(object value) {
            return new byte[] { (byte)value };
        }

        public override object ToObject(byte[] data) {
            return (sbyte)data[0];
        }
    }
    public class UShortConverter : ValueTypeConverter<ushort> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((ushort)value);
        }
        public override object ToObject(byte[] data) {
            return BitConverter.ToUInt16(data, 0);
        }

    }
    public class UIntConverter : ValueTypeConverter<uint> {

        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((uint)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToUInt32(data, 0);
        }
    }
    public class ULongConverter : ValueTypeConverter<ulong> {

        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((ulong)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToUInt64(data, 0);
        }
    }

    #endregion

    #region 浮点数
    public class FloatConverter : ValueTypeConverter<float> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((float)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToSingle(data, 0);
        }

    }

    public class DoubleConverter : ValueTypeConverter<double> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((double)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToDouble(data, 0);
        }
    }

    #endregion

    #region 字符
    public class CharConverter : ValueTypeConverter<char> {
        public override byte[] ToByteArray(object value) {
            return BitConverter.GetBytes((char)value);
        }

        public override object ToObject(byte[] data) {
            return BitConverter.ToChar(data, 0);
        }

    }

    public class StringConverter : ValueTypeConverter<string> {
        public override object ToObject(byte[] data) {
            return Encoding.UTF8.GetString(data);
        }

        public override byte[] ToByteArray(object value) {
            return Encoding.UTF8.GetBytes((string)value);
        }

    }
    #endregion
}
